// NFT铸造示例脚本
// 使用方法：
// 1. 单个铸造：node mint-examples.js single [合约地址] [接收地址] [metadata URI]
// 2. 批量铸造：node mint-examples.js batch [合约地址] [接收地址] [metadata hash]

const { ethers } = require('ethers');
require('dotenv').config();

// 配置信息
const config = {
    SEPOLIA_RPC_URL: process.env.SEPOLIA_RPC_URL || "https://sepolia.infura.io/v3/YOUR_INFURA_PROJECT_ID",
    PRIVATE_KEY: process.env.PRIVATE_KEY,
    GAS_PRICE: ethers.utils.parseUnits('20', 'gwei')
};

// 合约ABI
const contractABI = [
    "function mintNFT(address to, string memory tokenURI) public payable returns (uint256)",
    "function batchMintNFT(address to, string[] memory tokenURIs) public payable returns (uint256[] memory)",
    "function tokenURI(uint256 tokenId) public view returns (string)",
    "function ownerOf(uint256 tokenId) public view returns (address)",
    "function totalSupply() public view returns (uint256)",
    "event NFTMinted(address indexed to, uint256 indexed tokenId, string tokenURI)"
];

// 单个铸造NFT
async function mintSingleNFT(contractAddress, recipientAddress, metadataURI) {
    try {
        console.log("🎨 开始铸造单个NFT...\n");

        const provider = new ethers.providers.JsonRpcProvider(config.SEPOLIA_RPC_URL);
        const wallet = new ethers.Wallet(config.PRIVATE_KEY, provider);
        const contract = new ethers.Contract(contractAddress, contractABI, wallet);

        console.log("📋 铸造信息:");
        console.log("- 合约地址:", contractAddress);
        console.log("- 接收地址:", recipientAddress);
        console.log("- 元数据URI:", metadataURI);
        console.log("- 当前总供应量:", (await contract.totalSupply()).toString(), "\n");

        const tx = await contract.mintNFT(recipientAddress, metadataURI, {
            gasLimit: 500000,
            gasPrice: config.GAS_PRICE
        });

        console.log("⏳ 交易已发送，等待确认...");
        console.log("- 交易哈希:", tx.hash);

        const receipt = await tx.wait();
        const mintEvent = receipt.events?.find(event => event.event === 'NFTMinted');
        const tokenId = mintEvent?.args?.tokenId;

        console.log("\n✅ NFT铸造成功!");
        console.log("- Token ID:", tokenId?.toString());
        console.log("- Gas Used:", receipt.gasUsed.toString());
        console.log("- Block Number:", receipt.blockNumber);

        console.log("\n🌊 查看链接:");
        console.log("- OpenSea:", `https://testnets.opensea.io/assets/sepolia/${contractAddress}/${tokenId}`);
        console.log("- Etherscan:", `https://sepolia.etherscan.io/tx/${tx.hash}`);

        return tokenId;

    } catch (error) {
        console.error("❌ 铸造失败:", error.message);
        throw error;
    }
}

// 批量铸造NFT - 使用你的metadata数组结构
async function batchMintNFTs(contractAddress, recipientAddress, metadataHash) {
    try {
        console.log("🎨 开始批量铸造NFT...\n");

        const provider = new ethers.providers.JsonRpcProvider(config.SEPOLIA_RPC_URL);
        const wallet = new ethers.Wallet(config.PRIVATE_KEY, provider);
        const contract = new ethers.Contract(contractAddress, contractABI, wallet);

        // 创建5个NFT的metadata URI
        // 由于你的metadata是一个数组，我们需要为每个NFT创建单独的URI
        const metadataURIs = [
            `ipfs://${metadataHash}#0`, // myNFT1
            `ipfs://${metadataHash}#1`, // myNFT2  
            `ipfs://${metadataHash}#2`, // myNFT3
            `ipfs://${metadataHash}#3`, // myNFT4
            `ipfs://${metadataHash}#4`  // myNFT5
        ];

        console.log("📋 批量铸造信息:");
        console.log("- 合约地址:", contractAddress);
        console.log("- 接收地址:", recipientAddress);
        console.log("- NFT数量:", metadataURIs.length);
        console.log("- 当前总供应量:", (await contract.totalSupply()).toString());
        console.log("- Metadata Hash:", metadataHash, "\n");

        console.log("📝 将要铸造的NFT:");
        metadataURIs.forEach((uri, index) => {
            console.log(`  ${index + 1}. myNFT${index + 1} - ${uri}`);
        });

        const tx = await contract.batchMintNFT(recipientAddress, metadataURIs, {
            gasLimit: 2500000, // 更高的gas限制用于批量操作
            gasPrice: config.GAS_PRICE
        });

        console.log("\n⏳ 批量交易已发送，等待确认...");
        console.log("- 交易哈希:", tx.hash);

        const receipt = await tx.wait();
        const mintEvents = receipt.events?.filter(event => event.event === 'NFTMinted');
        const tokenIds = mintEvents?.map(event => event.args?.tokenId.toString());

        console.log("\n✅ 批量NFT铸造成功!");
        console.log("- 成功铸造数量:", tokenIds?.length || 0);
        console.log("- Token IDs:", tokenIds?.join(', '));
        console.log("- Gas Used:", receipt.gasUsed.toString());
        console.log("- Block Number:", receipt.blockNumber);

        console.log("\n🌊 查看链接:");
        tokenIds?.forEach((tokenId, index) => {
            console.log(`- myNFT${index + 1}: https://testnets.opensea.io/assets/sepolia/${contractAddress}/${tokenId}`);
        });
        console.log("- 交易记录:", `https://sepolia.etherscan.io/tx/${tx.hash}`);

        return tokenIds;

    } catch (error) {
        console.error("❌ 批量铸造失败:", error.message);
        throw error;
    }
}

// 主函数
async function main() {
    const args = process.argv.slice(2);

    if (args.length < 4) {
        console.log("❌ 参数不足!");
        console.log("\n📖 使用方法:");
        console.log("单个铸造: node mint-examples.js single [合约地址] [接收地址] [metadata URI]");
        console.log("批量铸造: node mint-examples.js batch [合约地址] [接收地址] [metadata hash]");
        console.log("\n💡 示例:");
        console.log("node mint-examples.js single 0x123... 0x456... ipfs://QmABC123...");
        console.log("node mint-examples.js batch 0x123... 0x456... QmABC123...");
        process.exit(1);
    }

    const [mode, contractAddress, recipientAddress, metadataParam] = args;

    // 验证环境变量
    if (!config.PRIVATE_KEY) {
        console.error("❌ 请设置 PRIVATE_KEY 环境变量");
        process.exit(1);
    }

    try {
        if (mode === 'single') {
            await mintSingleNFT(contractAddress, recipientAddress, metadataParam);
        } else if (mode === 'batch') {
            await batchMintNFTs(contractAddress, recipientAddress, metadataParam);
        } else {
            console.error("❌ 无效的模式，请使用 'single' 或 'batch'");
            process.exit(1);
        }

        console.log("\n🎉 操作完成!");

    } catch (error) {
        console.error("❌ 操作失败:", error);
        process.exit(1);
    }
}

// 如果直接运行此脚本
if (require.main === module) {
    main();
}

module.exports = {
    mintSingleNFT,
    batchMintNFTs
};
